#ifndef BASE_SYSTEM_LOG_CACHE_INCLUDE_ASYNC_LOGGER_H
#define BASE_SYSTEM_LOG_CACHE_INCLUDE_ASYNC_LOGGER_H

#include <atomic>
#include <condition_variable>
#include <functional>
#include <memory>
#include <mutex>
#include <thread>
#include <unordered_map>
#include <cstdlib>
#include "double_buffer.h"
#include "io_manager.h"
#include "i_output_strategy.h"
#include "log_level.h"
#include "system_log_config.h"
#include "system_log_error_code.h"

namespace Base {
namespace SystemLog {
using BackProcessTaskCallback = MessageConsumer;

// 配置结构体
struct LoggerConfig {
    uint32_t flushIntervalMs = DEFAULT_FLUSH_INTERVAL_MS;
    size_t softFlushThreshold = DEFAULT_SOFT_FLUSH_THRESHOLD;
    size_t hardFlushThreshold = DEFAULT_HARD_FLUSH_THRESHOLD;
    size_t maxBufferNodes = DEFAULT_MAX_BUFFER_NODES;
    LogLevel minLogLevel = LOG_LEVEL_INFO;
    
    // 添加验证方法
    bool Validate() const {
        return flushIntervalMs > 0 &&
               softFlushThreshold > 0 &&
               hardFlushThreshold > softFlushThreshold &&
               maxBufferNodes > 0;
    }
};

template<size_t SingleBufferSize = DEFAULT_BUFFER_SIZE>
class AsyncLogger {
public:
    using DoubleBuffer = Base::SystemLog::DoubleBuffer<SingleBufferSize>;
    using LockFreeRingBuffer = Base::SystemLog::LockFreeRingBuffer<SingleBufferSize>;

    static AsyncLogger& GetInstance() {
        static AsyncLogger instance;
        return instance;
    }

    AsyncLogger(const AsyncLogger &) = delete;
    AsyncLogger& operator=(const AsyncLogger &) = delete;

    ErrCode Append(const char* message, size_t len);
    ErrCode Append(const char* message, size_t len, LogLevel level, const char* file = nullptr);
    ErrCode Flush();
    ErrCode Start();
    ErrCode Stop();

    /**
     * 强制同步所有文件输出策略
     * 主要用于程序退出前确保数据完整性
     */
    ErrCode ForceSync();

    void SetFlushInterval(uint32_t milliseconds) {
        flushInterval_ = std::chrono::milliseconds(milliseconds);
    }

    void SetFlushThreshold(size_t softFlushThreshold = DEFAULT_SOFT_FLUSH_THRESHOLD,
        size_t hardFlushThreshold = DEFAULT_HARD_FLUSH_THRESHOLD) {
        softFlushThreshold_ = softFlushThreshold;
        hardFlushThreshold_ = hardFlushThreshold;
    }

    ErrCode AddOutputStrategy(OutputStrategyPtr strategy) {
        return ioManager_->AddStrategy(std::move(strategy));
    }

    void SetMinLevel(LogLevel level) {
        minLogLevel_ = level;
    }

    LogLevel GetMinLevel() const {
        return minLogLevel_;
    }
    
    // 监控接口
    struct BufferStats {
        size_t frontBufferSize;
        size_t backBufferSize;
        size_t totalNodes;
        size_t freeNodes;
        size_t memoryUsage;
        double utilization;
    };
    
    BufferStats GetBufferStats() const;
    
    // 配置更新
    ErrCode UpdateConfig(const LoggerConfig& newConfig);
    
    // 过滤和采样支持
    void SetFilter(std::function<bool(LogLevel, const char*, const char*)> filter) {
        filter_ = std::move(filter);
    }
    
    void SetSamplingRate(LogLevel level, double rate) {
        if (rate >= 0.0 && rate <= 1.0) {
            samplingRates_[level] = rate;
        }
    }
    
    double GetSamplingRate(LogLevel level) const {
        auto it = samplingRates_.find(level);
        return it != samplingRates_.end() ? it->second : 1.0;
    }

private:
    explicit AsyncLogger(BackProcessTaskCallback taskCallback)
        : taskCallback_(std::move(taskCallback)) {
        if (!taskCallback_) {
            throw std::invalid_argument("taskCallback function must be valid");
        }
    }
    AsyncLogger() : ioManager_(std::make_unique<IOManager>()) {}
    ~AsyncLogger();
    void BackendThreadFunc();
    ErrCode ProcessBuffer(LockFreeRingBuffer &buffer);
    void EmergencyFlush();
    ErrCode AppendInternal(const char* message, size_t len, LogLevel level, const char* file);

    BackProcessTaskCallback taskCallback_;
    DoubleBuffer doubleBuffer_;
    std::unique_ptr<std::thread> backendThread_;
    std::atomic<bool> running_{false};
    std::atomic<bool> forceFlush_{false};
    std::atomic<bool> processing_{false};
    std::mutex mutex_;
    std::condition_variable cond_;
    std::chrono::milliseconds flushInterval_{DEFAULT_FLUSH_INTERVAL_MS};
    size_t softFlushThreshold_{DEFAULT_SOFT_FLUSH_THRESHOLD};
    size_t hardFlushThreshold_{DEFAULT_HARD_FLUSH_THRESHOLD};
    std::unique_ptr<IOManager> ioManager_;
    LogLevel minLogLevel_{LOG_LEVEL_INFO};
    
    // 过滤和采样
    std::function<bool(LogLevel, const char*, const char*)> filter_;
    std::unordered_map<LogLevel, double> samplingRates_;
};

template<size_t SingleBufferSize>
AsyncLogger<SingleBufferSize>::~AsyncLogger()
{
    try {
        Stop();
    } catch (...) {
        syslog(LOG_ERR, "exception in AsyncLogger destructor");
    }
}

template<size_t SingleBufferSize>
ErrCode AsyncLogger<SingleBufferSize>::Start()
{
    if (running_.load(std::memory_order_acquire)) {
        return ERR_ALREADY_RUNNING;
    }
    running_.store(true, std::memory_order_release);
    forceFlush_.store(false, std::memory_order_release);
    processing_.store(false, std::memory_order_release);
    try {
        backendThread_ = std::make_unique<std::thread>([this] {
            BackendThreadFunc();
        });
        auto handle = backendThread_->native_handle();
        pthread_setname_np(handle, "log_backend");
        return ERR_OK;
    } catch (const std::system_error &e) {
        syslog(LOG_CRIT, "failed to start backend thread: %s", e.what());
        running_.store(false, std::memory_order_release);
        return ERR_THREAD_START_FAILED;
    }
}

template<size_t SingleBufferSize>
ErrCode AsyncLogger<SingleBufferSize>::Stop()
{
    if (!running_.load(std::memory_order_acquire)) {
        return ERR_NOT_RUNNING;
    }
    running_.store(false, std::memory_order_release);
    {
        std::lock_guard<std::mutex> lock(mutex_);
        cond_.notify_one();
    }
    try {
        if (backendThread_ && backendThread_->joinable()) {
            backendThread_->join();
        }
        if (doubleBuffer_.GetFrontSize() > 0) {
            EmergencyFlush();
        }
        return ERR_OK;
    } catch (const std::system_error &e) {
        syslog(LOG_ERR, "failed to join backend thread: %s", e.what());
        return ERR_THREAD_JOIN_FAILED;
    }
}

template<size_t SingleBufferSize>
ErrCode AsyncLogger<SingleBufferSize>::ForceSync()
{
    if (!ioManager_) {
        return ERR_INVALID_STATE;
    }
    
    // 首先强制刷新缓冲区
    ErrCode flushResult = Flush();
    if (flushResult != ERR_OK) {
        syslog(LOG_WARNING, "AsyncLogger::ForceSync: Flush failed with error %d", flushResult);
    }
    
    // 然后强制同步所有输出策略
    ErrCode syncResult = ioManager_->ForceSync();
    if (syncResult != ERR_OK) {
        syslog(LOG_WARNING, "AsyncLogger::ForceSync: IOManager ForceSync failed with error %d", syncResult);
        return syncResult;
    }
    
    return ERR_OK;
}

template<size_t SingleBufferSize>
ErrCode AsyncLogger<SingleBufferSize>::Append(const char* message, size_t len)
{
    if (!running_.load(std::memory_order_acquire)) {
        return ERR_LOGGER_NOT_RUNNING;
    }
    if (!message || len == 0) {
        return ERR_INVALID_ARGUMENT;
    }

    auto errCode = doubleBuffer_.Append(message, len);
    if (errCode != ERR_OK) {
        return errCode;
    }
    if (doubleBuffer_.GetFrontSize() >= softFlushThreshold_ && !processing_.load(std::memory_order_acquire)) {
        std::lock_guard<std::mutex> lock(mutex_);
        cond_.notify_one();
        return ERR_OK;
    }
    if (doubleBuffer_.GetFrontSize() >= hardFlushThreshold_) {
        std::lock_guard<std::mutex> lock(mutex_);
        forceFlush_.store(true, std::memory_order_release);
        cond_.notify_one();
        return ERR_OK;
    }
    return ERR_OK;
}

// 带过滤和采样的Append重载
template<size_t SingleBufferSize>
ErrCode AsyncLogger<SingleBufferSize>::Append(const char* message, size_t len, LogLevel level, const char* file)
{
    if (!running_.load(std::memory_order_acquire)) {
        return ERR_LOGGER_NOT_RUNNING;
    }
    if (!message || len == 0) {
        return ERR_INVALID_ARGUMENT;
    }
    
    // 级别过滤
    if (level < minLogLevel_) {
        return ERR_OK;
    }
    
    return AppendInternal(message, len, level, file);
}

template<size_t SingleBufferSize>
ErrCode AsyncLogger<SingleBufferSize>::Flush()
{
    if (!running_.load(std::memory_order_acquire)) {
        return ERR_LOGGER_NOT_RUNNING;
    }
    {
        std::lock_guard<std::mutex> lock(mutex_);
        forceFlush_.store(true, std::memory_order_release);
        cond_.notify_one();
    }
    for (int i = 0; i < DEFAULT_MAX_RETRY_TIMES; ++i) {
        if (doubleBuffer_.GetFrontSize() == 0 && 
            !processing_.load(std::memory_order_acquire)) {
            // 再做一次紧急flush，彻底消除并发窗口丢失
            EmergencyFlush();
            // 再次确认frontBuffer已空
            if (doubleBuffer_.GetFrontSize() == 0) {
                return ERR_OK;
            }
        }
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }
    return ERR_FLUSH_TIMEOUT;
}

template<size_t SingleBufferSize>
void AsyncLogger<SingleBufferSize>::BackendThreadFunc()
{
    while (running_.load(std::memory_order_acquire)) {
        std::unique_lock<std::mutex> lock(mutex_);
        auto checkCondition = [this] {
            return forceFlush_.load(std::memory_order_acquire) || !running_.load(std::memory_order_acquire) ||
                (doubleBuffer_.GetFrontSize() >= softFlushThreshold_);
        };
        cond_.wait_for(lock, flushInterval_, checkCondition);
        if (!running_.load(std::memory_order_acquire)) {
            break;
        }
        if (doubleBuffer_.GetFrontSize() == 0) {
            continue;
        }

        processing_.store(true, std::memory_order_release);
        if (auto errCode = doubleBuffer_.SafeSwap(); errCode != ERR_OK) {
            syslog(LOG_ERR, "safeSwap failed: %d", errCode);
            processing_.store(false, std::memory_order_release);
            continue;
        }
        lock.unlock();

        try {
            auto &backBuffer = doubleBuffer_.GetBackBuffer();
            ProcessBuffer(backBuffer);
        } catch (const std::exception &e) {
            syslog(LOG_CRIT, "exception during buffer processing: %s", e.what());
        }
        doubleBuffer_.ReleaseBackBuffer();
        processing_.store(false, std::memory_order_release);
    }
}

template<size_t SingleBufferSize>
ErrCode AsyncLogger<SingleBufferSize>::ProcessBuffer(LockFreeRingBuffer &buffer)
{
    const size_t dataSize = buffer.GetSize();
    if (dataSize == 0) {
        return ERR_OK;
    }

    if (taskCallback_ != nullptr) {
        buffer.Collect([this](const char* data, size_t size) {
            return taskCallback_(data, size);
        });
        return ERR_OK;
    }

    if (ioManager_ == nullptr) {
        syslog(LOG_ERR, "IOManager is not initialized");
        return ERR_IO_MANAGER_NOT_INITIALIZED;
    }
    buffer.Collect([this](const char* data, size_t size) {
        return ioManager_->Write(data, size);
    });
    // 刷新I/O
    ioManager_->Flush();
    return ERR_OK;
}

template<size_t SingleBufferSize>
void AsyncLogger<SingleBufferSize>::EmergencyFlush()
{
    syslog(LOG_WARNING, "performing emergency flush");
    
    if (doubleBuffer_.SafeSwap() != ERR_OK) {
        doubleBuffer_.EmergencySwap();
    }

    auto &backBuffer = doubleBuffer_.GetBackBuffer();
    ProcessBuffer(backBuffer);
    doubleBuffer_.ReleaseBackBuffer();
}

// 获取缓冲区统计信息
template<size_t SingleBufferSize>
auto AsyncLogger<SingleBufferSize>::GetBufferStats() const -> BufferStats
{
    BufferStats stats{};
    stats.frontBufferSize = doubleBuffer_.GetFrontSize();
    stats.backBufferSize = doubleBuffer_.GetBackSize();
    
    // 获取底层缓冲区的节点池统计
    const auto& frontBuffer = doubleBuffer_.GetFrontBuffer();
    auto pool = frontBuffer.GetBufferNodePool();
    
    if (pool) {
        stats.totalNodes = pool->GetTotalAllocatedCount();
        stats.freeNodes = pool->GetFreeNodesCount();
        stats.memoryUsage = pool->GetMemoryUsage();
        stats.utilization = pool->GetUtilization();
    }
    
    return stats;
}

// 配置更新
template<size_t SingleBufferSize>
ErrCode AsyncLogger<SingleBufferSize>::UpdateConfig(const LoggerConfig& newConfig)
{
    if (!newConfig.Validate()) {
        return ERR_INVALID_ARGUMENT;
    }
    
    // 暂停日志处理
    bool wasRunning = running_.load(std::memory_order_acquire);
    if (wasRunning) {
        Stop();
    }
    
    // 更新配置
    flushInterval_ = std::chrono::milliseconds(newConfig.flushIntervalMs);
    softFlushThreshold_ = newConfig.softFlushThreshold;
    hardFlushThreshold_ = newConfig.hardFlushThreshold;
    minLogLevel_ = newConfig.minLogLevel;
    
    // 重新创建缓冲区（如果需要）
    // 注意：这里简化了实现，实际可能需要更复杂的逻辑
    
    // 恢复日志处理
    if (wasRunning) {
        return Start();
    }
    
    return ERR_OK;
}

// 支持过滤和采样的Append方法
template<size_t SingleBufferSize>
ErrCode AsyncLogger<SingleBufferSize>::AppendInternal(const char* message, size_t len, LogLevel level, const char* file)
{
    // 应用过滤
    if (filter_ && !filter_(level, message, file)) {
        return ERR_OK; // 被过滤掉
    }
    
    // 应用采样
    double rate = GetSamplingRate(level);
    if (rate < 1.0 && (static_cast<double>(rand()) / RAND_MAX) > rate) {
        return ERR_OK; // 被采样掉
    }
    
    auto errCode = doubleBuffer_.Append(message, len);
    if (errCode != ERR_OK) {
        return errCode;
    }
    if (doubleBuffer_.GetFrontSize() >= softFlushThreshold_ && !processing_.load(std::memory_order_acquire)) {
        std::lock_guard<std::mutex> lock(mutex_);
        cond_.notify_one();
        return ERR_OK;
    }
    if (doubleBuffer_.GetFrontSize() >= hardFlushThreshold_) {
        std::lock_guard<std::mutex> lock(mutex_);
        forceFlush_.store(true, std::memory_order_release);
        cond_.notify_one();
        return ERR_OK;
    }
    return ERR_OK;
}

extern template class AsyncLogger<DEFAULT_BUFFER_SIZE>;
} // namespace SystemLog
} // namespace Base

#endif // BASE_SYSTEM_LOG_CACHE_INCLUDE_ASYNC_LOGGER_H